package licode.unisop.single.platform.infrastructure.repository.dao;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import licode.unisop.provider.info.AuthPlatPageInfo;
import licode.unisop.provider.info.SiAuthPlatToUserIn;
import licode.unisop.provider.utils.StrUtil;
import licode.unisop.provider.vo.SiPageResult;
import licode.unisop.single.platform.application.entity.AuthPlatformEntity;
import licode.unisop.single.platform.application.gateway.AuthPlatformDao;
import licode.unisop.single.platform.infrastructure.assembler.UniPlatformSingleAssembler;
import licode.unisop.single.platform.infrastructure.repository.mapper.AuthPlatformMapper;
import licode.unisop.single.platform.infrastructure.repository.po.AuthPlatformPO;
import licode.unisop.single.platform.infrastructure.utils.PageUtil;
import licode.unisop.types.util.IdGenUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * uni-platform-single
 *
 * @author licode
 * @date 2018-05-15 16:00:18
 */
@Component
public class AuthPlatformDaoImpl
        extends ServiceImpl<AuthPlatformMapper, AuthPlatformPO>
        implements AuthPlatformDao {
    @Resource
    private UniPlatformSingleAssembler uniPlatformSingleAssembler;

    @Override
    public void add(AuthPlatformEntity item) {
        super.save(uniPlatformSingleAssembler.fromAuthPlatformEntity(item));
    }

    @Override
    public void update(AuthPlatformEntity item) {
        super.updateById(uniPlatformSingleAssembler.fromAuthPlatformEntity(item));
    }

    @Override
    public void removeWithId(Serializable id) {
        super.removeById(id);
    }

    @Override
    public void removeGrantPlatform(SiAuthPlatToUserIn item) {
        super.lambdaUpdate()
                .eq(AuthPlatformPO::getUserId, item.getUserId())
                .in(AuthPlatformPO::getAuthPlatform, item.getPlatformIds())
                .remove();
    }

    @Override
    public void addGrantPlatform(SiAuthPlatToUserIn item) {
        List<AuthPlatformPO> res = super.lambdaQuery()
                .eq(AuthPlatformPO::getUserId, item.getUserId())
                .in(AuthPlatformPO::getAuthPlatform, item.getPlatformIds())
                .list();
        if (res != null && !res.isEmpty()) {
            res.forEach(plat -> item.getPlatformIds().remove(plat.getAuthPlatform()));
        } else {
            res = new ArrayList<>();
        }

        if (!item.getPlatformIds().isEmpty()) {
            res.clear();
            for (String authId : item.getPlatformIds()) {
                AuthPlatformPO authPlat = new AuthPlatformPO();
                authPlat.setId(IdGenUtil.buildPlatformId());
                authPlat.setPlatformId(item.getOwnerId());
                authPlat.setUserId(item.getUserId());
                authPlat.setAuthPlatform(authId);
                authPlat.setUpdateTime(LocalDateTime.now());
                authPlat.setCreateTime(authPlat.getUpdateTime());
                res.add(authPlat);
            }
            super.saveBatch(res);
        }
    }

    @Override
    public AuthPlatformEntity getWithId(Serializable id) {
        return uniPlatformSingleAssembler.fromAuthPlatform(super.getById(id));
    }

    @Override
    public SiPageResult<String> findAuthPlatformPage(AuthPlatPageInfo req) {
        Page<AuthPlatformPO> page = new Page<>(req.getCurrent(), req.getPageSize());
        page = super.lambdaQuery()
                .eq(StrUtil.isNotBlank(req.getUserId()), AuthPlatformPO::getUserId, req.getUserId())
                .in(null != req.getPlatformIds() && !req.getPlatformIds().isEmpty(),
                        AuthPlatformPO::getAuthPlatform, req.getPlatformIds())
                .page(page);

        return PageUtil.convertPage(page, (List<AuthPlatformPO> items) ->
                items.stream().map(AuthPlatformPO::getAuthPlatform).collect(Collectors.toList()));
    }
}
